package com.edu.exam.entity.grading.query;

import com.edu.exam.enums.grading.GradeStatus;
import com.edu.exam.enums.grading.GradeType;
import com.edu.exam.enums.grading.GradingStatus;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 成绩查询主表实体类
 * [所属模块] G-03 成绩查询模块
 * 对应数据库表：grade_query_main
 *
 *
 * <p>成绩查询主表实体用于存储成绩查询的核心数据，包含
 * 学生成绩信息、课程关联、班级信息、学期信息等。为成绩查询功能提供高效的数据存储和检索。</p>
 *
 * <p>核心功能：
 * - 成绩存储：存储学生的成绩基本信息和关联数据
 * - 查询优化：为高效查询提供合理的索引设计
 * - 状态管理：管理成绩的当前状态和变更历史
 * - 数据关联：关联学生、课程、班级、学期等基础数据
 * - 版本控制：支持成绩数据的版本管理和并发控制</p>
 *
 * @author 系统生成
 * @version 2.0
 * @since 2025-11-15
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@EntityListeners(AuditingEntityListener.class)
public class GradeQueryMain {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 学生ID
     *
     * <p>关联学生的唯一标识符。</p>
     */
    @Column(name = "student_id", nullable = false)
    private Long studentId;

    /**
     * 课程ID
     *
     * <p>关联课程的唯一标识符。</p>
     */
    @Column(name = "course_id", nullable = false)
    private Long courseId;

    /**
     * 班级ID
     *
     * <p>关联班级的唯一标识符。</p>
     */
    @Column(name = "class_id", nullable = false)
    private Long classId;

    /**
     * 学期ID
     *
     * <p>关联学期的唯一标识符。</p>
     */
    @Column(name = "semester_id", nullable = false)
    private Long semesterId;

    /**
     * 成绩类型
     *
     * <p>成绩的类型标识。
     * 支持的类型：DAILY（平时成绩）、MIDTERM（期中成绩）、FINAL（期末成绩）、QUIZ（测验）、ASSIGNMENT（作业）、OTHER（其他）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "grade_type", nullable = false, length = 30)
    private GradeType gradeType;

    /**
     * 分数
     *
     * <p>学生的成绩分数，精确到小数点后两位。</p>
     */
    @Column(name = "score", nullable = false, precision = 5, scale = 2)
    private BigDecimal score;

    /**
     * 等级
     *
     * <p>成绩等级评定，如优秀、良好、及格等。</p>
     */
    @Column(name = "grade_level", length = 10)
    private String gradeLevel;

    /**
     * 状态
     *
     * <p>成绩的当前状态。
     * 支持的状态：ACTIVE（有效）、INACTIVE（无效）、PENDING（待处理）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    private GradeStatus status = GradeStatus.DRAFT;

    /**
     * 成绩来源ID
     *
     * <p>原始成绩数据的来源ID，用于数据溯源。</p>
     */
    @Column(name = "source_grade_id")
    private Long sourceGradeId;

    /**
     * 成绩权重
     *
     * <p>成绩在总评中的权重比例。</p>
     */
    @Column(name = "weight", precision = 5, scale = 4)
    private BigDecimal weight;

    /**
     * 加权分数
     *
     * <p>成绩的加权分数值。</p>
     */
    @Column(name = "weighted_score", precision = 8, scale = 4)
    private BigDecimal weightedScore;

    /**
     * 排名
     *
     * <p>成绩在班级或课程中的排名。</p>
     */
    @Column(name = "rank")
    private Integer rank;

    /**
     * 百分位排名
     *
     * <p>成绩在班级或课程中的百分位排名。</p>
     */
    @Column(name = "percentile_rank", precision = 5, scale = 2)
    private BigDecimal percentileRank;

    /**
     * 补考分数
     *
     * <p>补考后的成绩分数。</p>
     */
    @Column(name = "makeup_score", precision = 5, scale = 2)
    private BigDecimal makeupScore;

    /**
     * 是否补考
     *
     * <p>标记是否为补考成绩。</p>
     */
    @Column(name = "is_makeup", nullable = false)
    private Boolean isMakeup = false;

    /**
     * 缓考标记
     *
     * <p>标记是否为缓考成绩。</p>
     */
    @Column(name = "is_deferred", nullable = false)
    private Boolean isDeferred = false;

    /**
     * 免修标记
     *
     * <p>标记是否为免修课程。</p>
     */
    @Column(name = "is_exempt", nullable = false)
    private Boolean isExempt = false;

    /**
     * 重修标记
     *
     * <p>标记是否为重修课程。</p>
     */
    @Column(name = "is_retake", nullable = false)
    private Boolean isRetake = false;

    /**
     * 重修次数
     *
     * <p>课程重修的次数。</p>
     */
    @Column(name = "retake_count")
    private Integer retakeCount = 0;

    /**
     * 备注
     *
     * <p>成绩的特殊说明或备注信息。</p>
     */
    @Column(name = "comment", columnDefinition = "TEXT")
    private String comment;

    /**
     * 成绩标签
     *
     * <p>JSON格式的成绩标签，用于分类和过滤。</p>
     */
    @Column(name = "grade_tags", columnDefinition = "TEXT")
    private String gradeTags;

    /**
     * 附加信息
     *
     * <p>JSON格式的附加成绩信息。</p>
     */
    @Column(name = "additional_info", columnDefinition = "TEXT")
    private String additionalInfo;

    // ===== 审计字段 =====

    /**
     * 创建时间
     */
    @CreatedDate
    @Column(name = "create_time", nullable = false, updatable = false)
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    @LastModifiedDate
    @Column(name = "update_time", nullable = false)
    private LocalDateTime updateTime;

    /**
     * 创建人ID
     */
    @Column(name = "creator_id")
    private Long creatorId;

    /**
     * 更新人ID
     */
    @Column(name = "updater_id")
    private Long updaterId;

    /**
     * 是否删除
     */
    @Column(name = "is_deleted", nullable = false)
    private Boolean isDeleted = false;

    /**
     * 版本号
     *
     * <p>用于乐观锁控制的版本号。</p>
     */
    @Version
    @Column(name = "version", nullable = false)
    private Integer version = 1;
}